package masking.wechat.sdk.mp;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import masking.wechat.sdk.AccessToken4Json;
import masking.wechat.sdk.MPAccount;
import masking.wechat.sdk.SimpleCache;
import masking.wechat.sdk.util.HttpUtils;
import masking.wechat.sdk.util.JacksonUtils;

/**
 * 微信公众号的AccessToken, 非用户个人AccessToken
 *
 */
public class MpAccessTokenUtil {

	
	private static final Map<String, SimpleCache<String>> TOKEN_MAP = new ConcurrentHashMap<>();

	public static String get(MPAccount mp) throws IOException {
		SimpleCache<String> token = TOKEN_MAP.get(mp.getAppId());
		if (token != null) {
			Date now = new Date();
			if (now.before(token.expireTime)) {
				return token.data;
			}
		}
		return refresh(mp);
	}

	private synchronized static String refresh(MPAccount mp) throws IOException {
		SimpleCache<String> token = TOKEN_MAP.get(mp.getAppId());
		if (token != null) {
			Date now = new Date();
			if (now.before(token.expireTime)) {
				return token.data;
			}
		}

		String response = HttpUtils.get(getFetchAccessTokenUrl(mp));
		AccessToken4Json newToken = JacksonUtils.getInstance().fromJson(response, AccessToken4Json.class);
		if (newToken.errcode == null || newToken.errcode == 0) {
			Calendar c = Calendar.getInstance();
			c.add(Calendar.HOUR, 1);
			token = new SimpleCache<String>(newToken.access_token, c.getTime());
			TOKEN_MAP.put(mp.getAppId(), token);
			return token.data;
		} else {
			return null;
		}
	}
	
	private static String getFetchAccessTokenUrl(MPAccount mp) {
		return "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
				+ mp.getAppId() + "&secret=" + mp.getSecret();
	}
}
